/*
 * Copyright 2009 Cedric Priscal
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */

package com.zhiwei.cppapp;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.os.SystemClock;

import com.zhiwei.cppapp.serialport.SerialPort;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;

/**
 * 抽象类，其他操作串口界面Activity的父类，初始化一些必要对象实例，和封装一个接收方法，异常的处理等。
 */
public abstract class SerialPortActivity extends Activity {

    protected MyApplication mApplication;//application对象
    protected SerialPort mSerialPort;//串口操作文件对象
    protected OutputStream mOutputStream;//输出流对象
    private InputStream mInputStream;//输入流对象
    private ReadThread mReadThread;//读取数据的线程

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mApplication = (MyApplication) getApplication();

        //初始化数据对象
        try {
            SystemClock.sleep(100);
            mSerialPort = mApplication.getSerialPort();
            mOutputStream = mSerialPort.getOutputStream();
            mInputStream = mSerialPort.getInputStream();

			/* Create a receiving thread */
            mReadThread = new ReadThread();
            mReadThread.start();
        } catch (SecurityException e) {
            displayError(R.string.error_security);
        } catch (IOException e) {
            displayError(R.string.error_unknown);
        } catch (InvalidParameterException e) {
            displayError(R.string.error_configuration);
        }
    }

    /**
     * 内部类，用于读取串口数据
     */
    private class ReadThread extends Thread {

        @Override
        public void run() {
            super.run();
            while (!isInterrupted()) {
                int size;
                try {
                    //一次读取64个字节
                    byte[] buffer = new byte[64];
                    if (mInputStream == null) {
                        return;
                    }
                    size = mInputStream.read(buffer);
                    //当输入流有数据时候，才做接收数据的响应，抽象方法，由不同子类具体实现
                    if (size > 0) {
                        onDataReceived(buffer, size);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    return;
                }
            }
        }
    }

    /**
     * 异常处理，显示错误信息
     *
     * @param resourceId
     */
    private void displayError(int resourceId) {
        AlertDialog.Builder b = new AlertDialog.Builder(this);
        b.setTitle("Error");
        b.setMessage(resourceId);
        //出现异常，就退出程序
        b.setPositiveButton("OK", new OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                SerialPortActivity.this.finish();
            }
        });
        b.show();
    }

    /**
     * 抽象方法，用于接收串口返回的数据
     * @param buffer
     * @param size
     */
    protected abstract void onDataReceived(final byte[] buffer, final int size);

    /**
     * Activity销毁时，注销线程，关闭串口
     */
    @Override
    protected void onDestroy() {
        if (mReadThread != null) {
            mReadThread.interrupt();
        }
        mApplication.closeSerialPort();
        mSerialPort = null;
        super.onDestroy();
    }
}
